﻿using System;
using System.Collections.Generic;
using CoreVirtuoso;
using CoreVirtuoso.Helpers;
using VDS.RDF.Query;
using VDS.RDF.Storage;
using VirtuosoDal.Config;
using VirtuosoDal.Helpers;
using VirtuosoDal.Repositories.RdfRepositories.Interfaces.Lgd;

namespace VirtuosoDal.Repositories.RdfRepositories.Lgd
{
   public class LgdSchemaRepository : ILgdSchemaRepository
   {
      public List<string> GetRootCategories()
      {
         string query = "prefix rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
                        "prefix owl:    <http://www.w3.org/2002/07/owl#> " +
                        "prefix  rdfs:     <http://www.w3.org/2000/01/rdf-schema#> " +
                        "prefix events:    <http://www.semanticweb.org/ontologies/2010/1/Events.owl#> " +
                        "SELECT DISTINCT ?child " +
                        "FROM @graph " +
                        "WHERE " +
                        "{ " +
                        "  ?child a owl:Class . " +
                        "  OPTIONAL " +
                        "  { " +
                        "    ?child rdfs:subClassOf ?parent " +
                        "  } " +
                        "  FILTER (!bound(?parent)) " +
                        "} " +
                        "ORDER BY ?child";

         SparqlParameterizedString sparqlParameterizedString = new SparqlParameterizedString(query);
         sparqlParameterizedString.SetUri("@graph", new Uri(Namespaces.LgdOntologyNamespace));

         using (var virtuosoManager = new VirtuosoManager(ConnectionStringsHelper.GetVirtuosoConnectionString()))
         {
            SparqlResultSet sparqlResultSet = QueryHelper.Query(virtuosoManager,
                                                                sparqlParameterizedString.ToString(), null);

            List<string> childCategories = SparqlResultSetConverter.ToListOfUris(sparqlResultSet);

            return childCategories;
         }
      }

      public List<string> GetChildCategories(string parentCategoryUri)
      {
         string query = "prefix rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
                        "prefix owl:    <http://www.w3.org/2002/07/owl#> " +
                        "prefix  rdfs:     <http://www.w3.org/2000/01/rdf-schema#> " +
                        "prefix events:    <http://www.semanticweb.org/ontologies/2010/1/Events.owl#> " +
                        "SELECT DISTINCT ?child " +
                        "FROM @graph " +
                        "WHERE " +
                        "{ " +
                        "  ?child rdfs:subClassOf @parent . " +
                        "  FILTER(?child != @parent) " +
                        "} " +
                        "ORDER BY ?child";

         SparqlParameterizedString sparqlParameterizedString = new SparqlParameterizedString(query);
         sparqlParameterizedString.SetUri("@graph", new Uri(Namespaces.LgdOntologyNamespace));
         sparqlParameterizedString.SetUri("@parent", new Uri(parentCategoryUri));

         using (var virtuosoManager = new VirtuosoManager(ConnectionStringsHelper.GetVirtuosoConnectionString()))
         {
            SparqlResultSet sparqlResultSet = QueryHelper.Query(virtuosoManager,
                                                                sparqlParameterizedString.ToString(), null);

            List<string> childCategories = SparqlResultSetConverter.ToListOfUris(sparqlResultSet);

            return childCategories;
         }
      }
   }
}